﻿using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using QW.Core.CommonModel;

namespace QW.Found.Middlewares
{
    /// <summary>
    /// 错误中间件
    /// </summary>
    public class ErrorHandlingMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILoggerFactory loggerFactory;

        public ErrorHandlingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            _next = next;
            this.loggerFactory = loggerFactory;
        }

        public async Task Invoke(HttpContext context)
        {
            var statusCode = context.Response.StatusCode;
            string msg = "";
            try
            {
                await _next(context);
                statusCode = context.Response.StatusCode;
            }
            catch (Exception ex)
            {
                #region 记录错误日志
                var igrone = false;
                if (ex is ArgumentException)
                    igrone = true;

                if (ex is BusinessException _ex)
                {
                    igrone = true;
                    if (_ex.Code == 401)
                    {
                        //权限不足
                        statusCode = _ex.Code;
                    }
                }

                if (!igrone)
                {
                    var logger = loggerFactory.CreateLogger("global.exception");
                    if (ex.TargetSite != null && ex.TargetSite.ReflectedType != null)
                    {
                        logger = loggerFactory.CreateLogger(ex.TargetSite.ReflectedType);
                    }
                    logger.LogError(ex, ex.Message);
                }
                #endregion
                msg = ex.Message;
            }
            finally
            {
                if (statusCode == HttpStatusCode.NotFound.GetHashCode())
                    msg = "未找到服务";
                else if (statusCode == HttpStatusCode.BadRequest.GetHashCode())
                    msg = "请求错误";
                else if (statusCode == HttpStatusCode.Forbidden.GetHashCode())
                    msg = "禁止访问";
                else if (statusCode == HttpStatusCode.Unauthorized.GetHashCode())
                {
                    context.Response.StatusCode = 401;
                }
                else if (statusCode != HttpStatusCode.OK.GetHashCode())
                    msg = "未知错误";

                if (!string.IsNullOrWhiteSpace(msg))
                    await HandleExceptionAsync(context, msg, statusCode);
            }
        }

        private static Task HandleExceptionAsync(HttpContext context, string msg, int code = 500)
        {
            var operateResult = CommonResult.FailResult(msg, code);
            var sta = context.Response.HasStarted;
            if (sta)
                return Task.FromResult(operateResult);
            var result = JsonConvert.SerializeObject(operateResult);//.ToLowerInvariant();
            context.Response.ContentType = "application/json;charset=utf-8";
            return context.Response.WriteAsync(result);
        }
    }
}